﻿// Tracer.cs
// This program contains a class that is responsible for tracing 
// information from the computer to a file

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace armsim
{
    /// <summary>
    /// Tracing class for the computer to trace contents to a file
    /// </summary>
    public class Tracer
    {

        /// <summary>
        /// Mechanism for writing text to a file
        /// </summary>
        private StreamWriter _traceFile;

        /// <summary>
        /// Flag indicating whether tracing is enabled or disabled
        /// </summary>
        private bool _tracingDisabled;

        /// <summary>
        /// The current number of traces for the current program running/stepping
        /// </summary>
        private int _traceCount;

        /// <summary>
        /// Initializes a new Tracer with a _traceCount of 1
        /// </summary>
        public Tracer()
        {
            _traceCount = 1;
        }

        /// <summary>
        /// Sets the _tracingDisabled boolean to false
        /// </summary>
        public void EnableTracing()
        {
            _tracingDisabled = false;
        }

        /// <summary>
        /// Sets the _tracingDisabled boolean to true
        /// </summary>
        public void DisableTracing()
        {
            _tracingDisabled = true;
        }

        /// <summary>
        /// Opens the trace file
        /// </summary>
        public void OpenTraceFile()
        {
            _traceFile = File.CreateText("trace.log");
        }

        /// <summary>
        /// Closes the trace file
        /// </summary>
        public void CloseTraceFile()
        {
            if (_traceFile != null)
            {
                _traceFile.Close();
            }
        }

        /// <summary>
        /// Resets the trace count to the value 1
        /// </summary>
        //public void ResetTraceCount()
        //{
         //   _traceCount = 1;
        //}

        /// <summary>
        /// Traces the current execution cycle into a log file and increments the _traceCount
        /// </summary>
        /// <param name="ram">Contains information to be traced</param>
        /// <param name="registers">Contains information to be traced</param>
        public void Trace(VirtualMemory ram, VirtualMemory registers)
        {
            if (_tracingDisabled) return;

            _traceFile.WriteLine("{0:D6} {1:X8} {2:X8} {3}   0={4:X8}  1={5:X8}  2={6:X8}  3={7:X8}", 
                                 _traceCount,
                                 (registers.ReadWord(VirtualMemory.PC) - 4u), 
                                 ram.CheckSum(),
                                 /*Memory.ExtractBits(registers.ReadWord(Memory.CPSR), 28, 31)*/"0000",
                                 registers.ReadWord(VirtualMemory.R0), registers.ReadWord(VirtualMemory.R1),
                                 registers.ReadWord(VirtualMemory.R2), registers.ReadWord(VirtualMemory.R3));

            _traceFile.WriteLine("        4={0:X8}  5={1:X8}  6={2:X8}  7={3:X8}  8={4:X8}  9={5:X8}",
                                 registers.ReadWord(VirtualMemory.R4), registers.ReadWord(VirtualMemory.R5),
                                 registers.ReadWord(VirtualMemory.R6), registers.ReadWord(VirtualMemory.R7),
                                 registers.ReadWord(VirtualMemory.R8), registers.ReadWord(VirtualMemory.R9)); // r4 r5 r6 r7 r8 r9

            _traceFile.WriteLine("       10={0:X8} 11={1:X8} 12={2:X8} 13={3:X8} 14={4:X8}",
                                 registers.ReadWord(VirtualMemory.R10), registers.ReadWord(VirtualMemory.R11),
                                 registers.ReadWord(VirtualMemory.R12), registers.ReadWord(VirtualMemory.R13),
                                 registers.ReadWord(VirtualMemory.R14));
                    // 10=01234567 11=01234567 12=01234567 13=01234567 14=01234567
            
            ++_traceCount;
        }



    }
}
